package pro.shushi.pamirs.hr.core.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import pro.shushi.pamirs.hr.api.model.auth.AppAuthResource;
import pro.shushi.pamirs.hr.core.manager.auth.AuthResourceManager;
import pro.shushi.pamirs.meta.annotation.fun.extern.Slf4j;
import pro.shushi.pamirs.meta.api.dto.model.PamirsUserDTO;
import pro.shushi.pamirs.meta.api.session.PamirsSession;
import pro.shushi.pamirs.meta.util.JsonUtils;
import pro.shushi.pamirs.user.api.cache.UserCache;
import pro.shushi.pamirs.user.api.constants.UserConstant;
import pro.shushi.pamirs.user.api.login.UserCookieLoginSimple;
import pro.shushi.pamirs.user.api.login.UserInfoCache;
import pro.shushi.pamirs.user.api.model.PamirsUser;
import pro.shushi.pamirs.user.api.utils.CookieUtil;
import pro.shushi.pamirs.user.api.utils.JwtTokenUtil;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;

@Slf4j
@RestController
@RequestMapping("/pamirs/auth")
public class AuthResourceController {

    @Autowired
    private AuthResourceManager authResourceManager;

    @RequestMapping(value = "/auth_resource_get", method = RequestMethod.GET)
    public String getAuthResource(HttpServletRequest request) throws Exception {
        // 根据获取到的Authorization或者Cookie分别进行出来
        PamirsUserDTO pamirsUserDTO = handleAuthorizationOrCookie(request);
        if (pamirsUserDTO == null) {
            log.warn("根据请求获取的用户信息为空");
            return "";
        }

        List<AppAuthResource> authResources = authResourceManager.fetchActionPermissions();
        return JsonUtils.toJSONString(authResources, SerializerFeature.DisableCircularReferenceDetect,
                SerializerFeature.WriteDateUseDateFormat, SerializerFeature.WriteMapNullValue);
    }

    /**
     * @return
     */
    public PamirsUserDTO handleAuthorizationOrCookie(HttpServletRequest request) {
        String authorization = request.getHeader(UserConstant.USER_TOKEN_HEADER);
        String sessionId = request.getHeader(UserConstant.USER_SESSION_ID);
        if (StringUtils.isNotBlank(authorization)) {
            return handleAuthorization(authorization);
        } else {
            return handleCookie(sessionId);
        }
    }

    /**
     * @return
     */
    public PamirsUserDTO handleAuthorization(String authorization) {
        String tokenHead = UserConstant.USER_TOKEN_PREFIX;
        if (authorization != null && !authorization.startsWith(tokenHead)) {
            log.warn("authorization:{},格式不符合规范", authorization);
            return null;
        }
        String resource = JwtTokenUtil.getKeyFromToken(authorization.substring(tokenHead.length()));
        Map<String, String> mapResource = JSON.parseObject(resource, Map.class);
        String openId = mapResource.get("openId");
        PamirsUser user = UserInfoCache.queryUserById(Long.parseLong(openId)); //TODO 查询不到用户报错
        if (user == null) {
            log.warn("根据openId:{} 获取用户信息为空", openId);
            return null;
        }

        PamirsUserDTO pamirsUser = new PamirsUserDTO();
        pamirsUser.setUserId(user.getId());
        pamirsUser.setUserCode(user.getCode());
        pamirsUser.setUserName(user.getName());
        pamirsUser.setEmail(user.getEmail());
        pamirsUser.setPhone(user.getPhone());
        pamirsUser.setLangCode("zh-CN");

        putEnv(pamirsUser);

        String sessionId = PamirsSession.getSessionId();
        HttpServletResponse httpServletResponse = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
        UserCookieLoginSimple userCookieLoginSimple = new UserCookieLoginSimple();
        if(StringUtils.isBlank(sessionId)){
            sessionId = userCookieLoginSimple.createSessionId();
        }
        String cacheKey = userCookieLoginSimple.parseSessionId(sessionId);
        UserCache.putCache(cacheKey, pamirsUser);
        try {
            CookieUtil.set(httpServletResponse, UserConstant.USER_SESSION_ID, sessionId);
        } catch (Exception e) {
            log.error("SSO Login Cookie Set Err", e);
        }

        return pamirsUser;
    }

    /**
     * @return
     */
    public PamirsUserDTO handleCookie(String sessionId) {
        if (StringUtils.isBlank(sessionId)) {
            return null;
        }
        PamirsUserDTO pamirsUser = UserCache.get(sessionId);
        if (pamirsUser == null) {
            log.warn("sessionId:{} 获取用户信息为空", sessionId);
            return null;
        }

        PamirsUser user = UserInfoCache.queryUserById(pamirsUser.getUserId());
        if (user == null) {
            log.warn("根据用户ID:{} 获取用户信息为空", pamirsUser.getUserId());
            return null;
        }
        // 更新用户信息
        pamirsUser.setUserId(user.getId());
        pamirsUser.setUserCode(user.getCode());
        pamirsUser.setUserName(user.getName());
        pamirsUser.setEmail(user.getEmail());
        pamirsUser.setPhone(user.getPhone());
        pamirsUser.setLangCode("zh-CN");

        putEnv(pamirsUser);

        HttpServletResponse httpServletResponse = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
        UserCookieLoginSimple userCookieLoginSimple = new UserCookieLoginSimple();
        String cacheKey = userCookieLoginSimple.parseSessionId(sessionId);
        UserCache.putCache(cacheKey, pamirsUser);
        try {
            CookieUtil.set(httpServletResponse, UserConstant.USER_SESSION_ID, sessionId);
        } catch (Exception e) {
            log.error("SSO Login Cookie Set Err", e);
        }

        return pamirsUser;
    }

    protected void putEnv(PamirsUserDTO user) {
        PamirsSession.setUserId(user.getUserId());
        PamirsSession.setUserName(user.getUserName());
        PamirsSession.setLang(user.getLangCode());
        PamirsSession.setUserCode(user.getUserCode());
    }
}
